#ifndef _MSG_H
#define _MSG_H
#include "os_wrap.h"

#define MSG_BLOCKING       (0) // Blocking call, can't call by ISR
#define MSG_NONBLOCKING    (1) // Non-blocking call, can call by ISR
#define MSG_API            (2) // Function call directly
#define MSG_OVERWR         (3) // Non-blocking , message block will be overwritten by next msg

#define TASK_CRITICAL(statement)    \
do {    \
    OSSchedLock();  \
    statement       \
    OSSchedUnlock();\
} while (0);    

enum {
	SYS_MSG_USB_EP0_TX_INT=0,
	SYS_MSG_USB_EP1_TX_INT,
	SYS_MSG_USB_EP2_TX_INT,
	SYS_MSG_USB_EP3_TX_INT,
	SYS_MSG_USB_EP0_RX_INT,
	SYS_MSG_USB_EP1_RX_INT,
	SYS_MSG_USB_EP2_RX_INT,
	SYS_MSG_USB_EP3_RX_INT,
	SYS_MSG_USB_RESET_INT,
	SYS_MSG_USB_SUSPEND_INT,
	SYS_MSG_USB_DMA_EP0_TX_INT,	
	SYS_MSG_USB_DMA_EP1_TX_INT,	
	SYS_MSG_USB_DMA_EP2_TX_INT,	
	SYS_MSG_USB_DMA_EP3_TX_INT,	
	SYS_MSG_USB_DMA_EP0_RX_INT,	
	SYS_MSG_USB_DMA_EP1_RX_INT,	
	SYS_MSG_USB_DMA_EP2_RX_INT,	
	SYS_MSG_USB_DMA_EP3_RX_INT
};
typedef struct _msg_t
{
    MMP_ULONG src_id ;//FIXME: remove this later
    MMP_ULONG dst_id ;//FIXME: remove this later
    MMP_ULONG msg_id ;
    MMP_ULONG msg_sub_id ; 
    void      *msg_data ;
    MMPF_OS_SEMID *msg_sem;
    MMP_ULONG err ;//FIXME: remove this later
} msg_t ;


typedef struct _msg_queue_t
{
    MMP_USHORT rd_i ;
    MMP_USHORT wr_i ;
    MMP_USHORT msg_len;
    MMP_ULONG  *msg_q ;
} msg_queue_t ;
 
#define L1_MSG_SIZE sizeof(msg_t)
#define L1_MSG_Q_SIZE   (20)

#define MSG_QUEUE_NUMS 3
/* PCAM Task use index 0,
   SYS Task use index 1 
   USB Task use index 2
   */
   
enum {
    MSG_ERROR_NONE = 0,
    MSG_INIT_ERR,
    MSG_CREATE_SEM_ERR,
    MSG_POST_ERR,
    MSG_WAIT_SEM_TIMEOUT,
    MSG_ACQUIRE_SEM_ERR,
    MSG_QUEUE_FULL_ERR
};

enum {
    USBCTL_MSG_START_PREVIEW=0,
    USBCTL_MSG_STOP_PREVIEW,
    USBCTL_MSG_RESET_SENSOR,
#if (CUSTOMER == PNS)
    USBCTL_MSG_POPUP_LOOP,
#endif
#if XU_FRAMEBASE_CAPTURE && ((CHIP_AIT8451==0) || BIND_SENSOR_AR0832E)
    USBCTL_MSG_CAPTURE_REPEAT,
#endif
    USBCTL_MSG_AUDIO_START,
    USBCTL_MSG_AUDIO_STOP,
    USBCTL_MSG_AUDIO_SET_SAMPLERATE,
    USBCTL_MSG_TRIGGER_SCANNING,
    USBCTL_MSG_START_DECODING,
    USBCTL_MSG_OTHERS
};

msg_t *allocate_msg( int id );
msg_t *get_msg(int id);
msg_t *get_overwr_msg(int id);
void free_msg(void *msg, int id);
MMP_USHORT send_msg(msg_t *msg,MMP_USHORT *ret_err, int id);
MMP_USHORT post_msg(msg_t *msg, int id);
MMP_USHORT init_msg_queue(int id, MMPF_OS_FLAGID os_id, MMP_ULONG flags);

#endif
